class Food{
}
class Fruit extends Food{
}
class apple extends Fruit{
}
class banana extends Fruit{
}

public class Plate<T>{//设置一个泛型类

    public T array;

public void set(T array){
    this.array = array;
}

public T get(){
    return array;
}


public static void main(String[] args) {
       Plate<apple> x1= new Plate<>();  //表示只能放入apple对象
       x1.set(new apple());
       Plate<banana> x2 = new Plate<>();//同理
       x2.set(new banana());

       Plate<Food> x3 = new Plate<>();
       x3.set(new Food());

       fun1(x1);
       fun1(x2);
       fun2(x3);
    }

    //通配符的上界
public static void fun1(Plate<? extends Fruit> z){//指定一个容器，存放的类型是Fruit或子类
    System.out.println(z.get());

//    z.set(new apple());
//    z.set(new banana());     设置失败，不能知道传入的是哪个子类

    Fruit fruit = z.get();      //得到的一定是Fruit的子类
    System.out.println(fruit);  //成功了，同时打印了apple跟banana

}

public static void fun2(Plate<? super Fruit> t){
    t.set(new Fruit());     //可以放自己以及子类
    t.set(new apple());
    t.set(new banana());    //会打印最后一个传入的值


//   Food food = new Fruit();
//   Fruit fruit2 = (Fruit) food;     //这样做就安全

//    Fruit fruit2=(Fruit) new Food();//但是这样直接指向不安全,打印不出来结果

//    Fruit fruit3 = (Fruit) t.get(); //觉得这个写法突兀的就向上看,也不安全

    Object o = t.get();               //Object来接收就安全了
    System.out.println(o);
}

}
